package pub.cleangao.mybatis.execution;

import lombok.Data;
import lombok.EqualsAndHashCode;
import pub.cleangao.mybatis.expression.JoinExpression;
import pub.cleangao.mybatis.expression.Tables;
import pub.cleangao.mybatis.expression.WhereExpression;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


@EqualsAndHashCode(callSuper = true)
@Data
public class ReadExecution extends AbstractExecution {


    private boolean singleTable = true;

    private List<WhereExpression> whereExpressionList;

    // ---- 单表查询
    public static ReadExecution startSelect(String table) {
        ReadExecution execution = new ReadExecution();
        execution.setTable(table);
        execution.setColumnList(new ArrayList<>());
        execution.setSingleTable(true);
        return execution;
    }


    private String table;

    private List<String> columnList;

    // ---- 多表联合查询
    public static ReadExecution startSelect(Tables tables) {
        ReadExecution execution = new ReadExecution();
        execution.setSingleTable(false);
        execution.setJoinExpressionList(tables.getJoinExpressionList());
        return execution;
    }

    private List<JoinExpression> joinExpressionList;


    @Override
    public Object runInDataSource(Connection connection) throws SQLException {

        if (whereExpressionList != null && !whereExpressionList.isEmpty()) {
            whereExpressionList.sort((o1, o2) -> {
                return o1.index() - o2.index();
            });
        }
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT ");
        if (singleTable) {
            if (columnList == null || columnList.isEmpty()) {
                sql.append(" * ");
            } else {
                for (String column : columnList) {
                    sql.append(column);
                    sql.append(",");
                }
                sql.delete(sql.length() - 1, sql.length());
            }
            sql.append(" FROM ");
            sql.append(table);
        } else {
            char a = 'a';
            for (int i = joinExpressionList.size() - 1; i >= 0; i--) {
                JoinExpression joinExpression = joinExpressionList.get(i);
                String tableAlias = String.valueOf((char) ((int) a + i));
                if (joinExpression.columns() == null || joinExpression.columns().isEmpty()) {
                    sql.append(tableAlias).append(".*,");
                } else {
                    for (String column : joinExpression.columns()) {
                        sql.append(tableAlias).append(".").append(column).append(",");
                    }
                }
            }
            sql.delete(sql.length() - 1, sql.length());
            sql.append(" FROM ");
            for (int i = joinExpressionList.size() - 1; i > 0; i--) {
                JoinExpression joinExpression = joinExpressionList.get(i);
                String tableAlias = String.valueOf((char) ((int) a + i));
                sql.append(joinExpression.table()).append(" ").append(tableAlias);
                sql.append(" ");
                sql.append(joinExpression.joint().value());
                sql.append(" ");
                sql.append(joinExpression.getPrevTable());
                String tableAliasPre = String.valueOf((char) ((int) a + i - 1));
                sql.append(" ON ");
                sql.append(tableAlias)
                        .append(".")
                        .append(joinExpression.getEqColumn())
                        .append("=")
                        .append(tableAliasPre)
                        .append(".")
                        .append(joinExpression.getPrevEqColumn());
            }
        }
        return connection.prepareStatement(generateWhereClause(sql, whereExpressionList)).executeQuery();

    }
}
